package com.goo.utils;

import java.math.BigInteger;

/**
 * 进制转换工具
 *
 * @author hasee
 */
public class RadixUtils {

    /**
     * 将 2进制字符串转换成 8进制字符串
     *
     * @param binaryStr: 二进制字符串，例如1001
     * @return
     */
    public static String binaryToOctalString(String binaryStr) {
        //二进制转八进制
        String octalString = Integer.toOctalString(Integer.parseInt(binaryStr, 2));
//        String octalString = Integer.toOctalString(Integer.parseInt("1001", 2));
        return octalString;
    }

    /**
     * 将 2进制字符串转换成 10进制字符串
     *
     * @param binaryStr: 二进制字符串，例如 1001
     * @return
     */
    public static String binaryToDecimalString(String binaryStr) {
        String deciaml = Integer.valueOf(binaryStr, 2).toString();
        return deciaml;
    }

    /**
     * 将 2进制转换成 16进制字符串
     *
     * @param binaryStr: 二进制字符串，例如 1001
     * @return
     */
    public static String binaryToHexString(String binaryStr) {
        //二进制转十六进制
//        Integer.toHexString(Integer.parseInt(1001, 2));
        String toHexString = Integer.toHexString(Integer.parseInt(binaryStr, 2));
        return toHexString;
    }

    /**
     * 将 2进制转换成 16进制字符串
     *
     * @param buf: 二进制字数组
     * @return
     */
    public static String binaryToHexString(byte buf[]) {
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < buf.length; i++) {
            String hex = Integer.toHexString(buf[i] & 0xFF);
            if (hex.length() == 1) {
                hex = '0' + hex;
            }
            sb.append(hex.toUpperCase());
        }
        return sb.toString();
    }

    /**
     * 将 8进制字符串转换成 2进制字符串
     *
     * @param octalStr: 8进制字符串，例如 12
     * @return
     */
    public static String octalToBinaryString(String octalStr) {
        //八进制转成二进制
        String binaryString = Integer.toBinaryString(Integer.valueOf(octalStr, 8));
        return binaryString;
    }

    /**
     * 将 8进制字符串转换成 16进制字符串
     *
     * @param octalStr: 8进制字符串，例如 12
     * @return
     */
    public static String octalToHexString(String octalStr) {
        //八进制转成十六进制
        String toHexString = Integer.toHexString(Integer.valueOf(octalStr, 8));
        return toHexString;
    }

    /**
     * 将 8进制字符串转换成 10进制字符串
     *
     * @param octalStr: 8进制字符串，例如 12
     * @return
     */
    public static Integer octalToDecimalString(String octalStr) {
        BigInteger bigint = new BigInteger(octalStr, 8); // 8进制转10进制
        Integer decimal = bigint.intValue();
        return decimal;
    }

    /**
     * 将 10进制数字转为 2进制字符串
     *
     * @param decimal:十进制数字
     * @return
     */
    public static String decimalToBinaryString(Integer decimal) {
        String binaryString = Integer.toBinaryString(decimal);
        return binaryString;
    }

    /**
     * 将 10进制数字转为 8进制字符串
     *
     * @param decimal:十进制数字
     * @return
     */
    public static String decimalToOctalString(Integer decimal) {
        String octalString = Integer.toOctalString(decimal);
        return octalString;

    }

    /**
     * 将 10进制数字转为 16进制字符串
     *
     * @param decimal:十进制数字
     * @return
     */
    public static String decimalToHexString(Integer decimal) {
        String hex = Integer.toHexString(decimal);
        return hex;
    }


    /**
     * 将 16进制字符串转换为 2进制
     *
     * @param hexStr: 16进制字符串
     * @return
     */
    public static String hexToBinaryString(String hexStr) {
        //十六进制转成二进制
        String binaryString = Integer.toBinaryString(Integer.valueOf(hexStr, 16));
        return binaryString;
    }

    /**
     * 将 16进制字符串转换为 2进制
     *
     * @param hexStr: 16进制字符串
     * @return
     */
    public static byte[] hexToBinaryString2(String hexStr) {
        if (hexStr.length() < 1)
            return null;
        byte[] result = new byte[hexStr.length() / 2];
        for (int i = 0; i < hexStr.length() / 2; i++) {
            int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
            int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);
            result[i] = (byte) (high * 16 + low);
            System.out.println("将16进制字符串转换为二进制： " + result[i]);
        }
        return result;
    }

    /**
     * 将 16进制字符串转换为 8进制
     *
     * @param hexStr: 16进制字符串
     * @return
     */
    public static String hexToOctalString(String hexStr) {
        //十六进制转成八进制
        Integer decm = Integer.valueOf(hexStr, 16);
        String octalString = Integer.toOctalString(decm);
        return octalString;
    }


    /**
     * 将 16进制字符串转为 10进制数字
     *
     * @param hexStr: 16进制字符串
     * @return
     */
    public static Long hexToDecimalString(String hexStr) {
        BigInteger bigint = new BigInteger(hexStr, 16);
        Long numb = bigint.longValue();
        return numb;
    }


    /**
     * 将char 强制转换为byte
     *
     * @param ch
     * @return
     */
    public static byte charToByteAscii(char ch) {
        byte byteAscii = (byte) ch;
        return byteAscii;
    }

    /**
     * 方法二：将char直接转化为int，其值就是字符的ascii
     *
     * @param ch
     * @return
     */
    public static byte charToByteAscii2(char ch) {
        byte byteAscii = (byte) ch;
        return byteAscii;
    }

    /**
     * 同理，ascii转换为char 直接int强制转换为char
     *
     * @param ascii
     * @return
     */
    public static char byteAsciiToChar(int ascii) {
        char ch = (char) ascii;
        return ch;
    }

    /**
     * 求出字符串的ASCII值和
     * 注意，如果有中文的话，会把一个汉字用两个byte来表示，其值是负数
     */
    public static int sumStrAscii(String str) {
        byte[] bytestr = str.getBytes();
        int sum = 0;
        for (int i = 0; i < bytestr.length; i++) {
            sum += bytestr[i];
        }
        return sum;
    }


    /**
     * 将char 字符转为16进制数据
     *
     * @param ch：字符
     * @return
     */
    public static String charToHexString(char ch) {
        //数据转换
        int b = (int) RadixUtils.charToByteAscii(ch);
        String str = RadixUtils.decimalToHexString(b);
        return str;
    }


    /**
     * 将char 字符转为16进制数据,在转为int类型
     *
     * @param ch：字符
     * @return
     */
    public static byte charToByte(char ch) {
        //数据转换
        String str = charToHexString(ch);
        int code = Integer.parseInt(str);
        return (byte) code;
    }

    public static void main(String[] args) {

        char ch = '9';
        int b = charToByteAscii(ch);
        System.out.println("将char字符转为ascii： " + b);
        System.out.println("将ascii 转为 char字符： " + byteAsciiToChar(b));
        System.out.println("将ascii 转为 16进制： " + RadixUtils.decimalToHexString(b));


        int numb = 48;
        System.out.println("  10进制转为2进制： " + decimalToBinaryString(numb));
        System.out.println("  10进制转为8进制： " + decimalToOctalString(numb));
        String hex = decimalToHexString(numb);
        System.out.println("  10进制转为16进制： " + hex);


        System.out.println("    16进制字符 " + hex + " 转为8进制： " + hexToOctalString(hex));
        System.out.println("    16进制字符 " + hex + " 转为10进制： " + hexToDecimalString(hex));
        String binaryString = hexToBinaryString(hex);
        System.out.println("    16进制字符 " + hex + " 转为2进制： " + binaryString);


        System.out.println("    2进制字符 " + hex + " 转为8进制： " + binaryToOctalString(binaryString));
        System.out.println("    2进制字符 " + hex + " 转为10进制： " + binaryToDecimalString(binaryString));
        System.out.println("    2进制字符 " + hex + " 转为16进制： " + binaryToHexString(binaryString));


        // 2，8，16进制转换成10进制
// 使用Integer.parseInt()方法；转换成负数只需要在字符串前面加上负号-；大于Integer.MAX_VALUE或小于Integer.MIN_VALUE的转换将会抛出错误。
//        int b = Integer.parseInt("1001", 2);    // 2进制转10进制
//        int o = Integer.parseInt("12", 8);    // 8进制转10进制
//        int h = Integer.parseInt("123ABC", 16);    // 16进制转10进制
//
//        System.out.println("=== 字符串2，8，16进制转换成整型10进制 ===");
//        System.out.println("1001(2) --> " + b + "(10)");
//        System.out.println("12(8) --> " + o + "(10)");
//        System.out.println("123ABC(16) --> " + h + "(10)");

        // 2，8，16进制转换成10进制
// 使用Integer.valueOf()方法；转换成负数只需要在字符串前加上负号-；大于Integer.MAX_VALUE或小于Integer.MIN_VALUE的转换将会抛出错误。
//        Integer b = Integer.valueOf("1001", 2); // 2进制转10进制
//        Integer o = Integer.valueOf("12", 8);    // 8进制转10进制
//        Integer h = Integer.valueOf("123ABC", 16);    // 16进制转10进制
//
//        System.out.println("=== Integer.valueOf() 字符串2，8，16进制转换成整型10进制 ===");
//        System.out.println("1001(2) --> " + b + "(10)");
//        System.out.println("12(8) --> " + o + "(10)");
//        System.out.println("123ABC(16) --> " + h + "(10)");

        // 2，8，16进制转换成10进制
        // 使用BigInteger对象；转换成负数只需要在字符串前加上负号-；BigInteger能够存储比Long.MAX_VALUE更大的数；
//        BigInteger b = new BigInteger("1001", 2); // 2进制转10进制
//        BigInteger o = new BigInteger("12", 8);    // 8进制转10进制
//        BigInteger h = new BigInteger("123ABC", 16);// 16进制转10进制
//
//        System.out.println("=== 基于BigInteger的进制转换 字符串2，8，16进制转换成整型10进制 ===");
//        System.out.println("1001(2) --> " + b + "(10)");
//        System.out.println("12(8) --> " + o + "(10)");
//        System.out.println("123ABC(16) --> " + h + "(10)");

    }
}
